iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 15
0

凡事都有例外,寫程式也是如此。處理Exception可以說是最麻煩,最考驗軟體工程師的地方了。它可以很簡單的處理,也可以用很漂亮的方法來包裝:這真的就是技巧了。

但在那之前,我們先討論一件事:什麼是Exception?

OutOfMemoryError or OutOfMemoryException?

通常而言,如果是和本身資源無關,系統雖然糟遇重大困難但如果適度的處理仍能繼續的事件,就叫例外。最常見的像陣列讀超過數量的IndexOutOfRangeException:這類的事件通常都可以預防,最差最差狀況就是用try-catch來補捉,沒什麼了不起的學問。
但如果發生了重大的事件是在建立本身的Platform上,系統無法補捉或必需用非常手段來處理的,那就是錯誤了,例如像OutOfMemoryError, StackOverflowError。

這個在Java有很嚴格的區別,但在C#就全部都叫Exception了(我就懶)。

對於這個問題後面有其他的討論。

命名原則

所以根據上面的說明可以知道,原則上如果系統是安放在platform上,理論上Error不太容易觸碰到,除非寫了unsafe code,系統往底層寫,同時為了安全做了一些底層等級的處理。無論是那一種,它的命名原則都是:在字尾加上Exception,例如

    class IllegalArgumentsException : Exception

在使用時,也是用camelCase

    try
    {
    }
    catch (OutOfOrderException outOfOrderException)
    {
        //do something
    }
    catch (Exception exception)
    {
         //do something
    }
    finally
    {
    }

如果

catch啦,那次不catch

即然try catch那麼方便,那有什麼好講的?
我引述一段在網路上看到的回文:

Handling a stack overflow is not the right solution, instead, you must ensure that your program does not overflow the stack.

就像前面提到的"陣列讀超過數量的IndexOutOfRangeException",處理Exception最好的方法,應該是在它掉進catch section之前,就把可能發生的情況都處理掉,讓程式不會發生這類的Exception。或許IndexOutOfRangeException是一個非常初階的錯誤,但其實80%的Exception都是可以被處理掉的,在SDK文件裡也可以看到相關的方法會因為什麼情況拋出Exception。
https://ithelp.ithome.com.tw/upload/images/20200916/20111458fO7DQjkayi.png
所以在使用這類的API時,除了知道用法外,也應該要從Exception這節,知道一些相關使用的限制。

不要吞掉Exception

這是一個很常見的問題:為了不要讓程式出錯,用空的catch把Excption吞掉。
就像上面說的,Exception應該是軟體工程師一定要處理的問題,就算在共識上不處理,也應該要做三件事

  1. 在catch段裡說明不處理的原因
  2. 把exception的內容寫到log裡
  3. 定期review相關的作法:這類的錯誤可能會造成除錯困難或產生技術債,所以應該要想辦法另外處理。

Don't Drop the ball

如果程式補捉到了Exception,理想的處理方法應該是在當下處理掉:寫Log、排除、重試都是很適合的做法,但不要原封不動的把錯誤又拋到上一層去:連資料庫失敗,把同樣的Exception拋到上層並不能解決問題。如果真的要再拋出例外,應該把相關的例外增加更多的訊息,讓接收例外的程式知道發生的原因。

Exception的排列

大多數的情況下,應該都可以補捉到大於一個的Exception,它們可能歸類在不同類別下。就像前面提到的,在SDK裡可以查到相關方法會拋出的例外,所以在程式裡也應該處理可能無法排除的例外。
那在排列例外補捉時,要把最常發生的例外方在最上層,然後依序往下到最後一個是General Exception,就是Exception它本人,也在這裡做最一般的處理法。

乾淨的程式 vs 效能

有些工程師喜歡用例外當成流程控制的一部份,但我個人認為並不是個很好的做法:例外還是應該保留給無法預期的情況。但如果整個流程裡沒有任何地方可以把錯誤告訴呼叫者,那例外就是唯一的方法告訴呼叫者應該修改相關的行為。但try-catch在效能上或多或少會有些影響,所以權衡之間還是要考量一下是否值得這樣做。

例外處理其實還滿多東西可以講的,前輩泰迪也把他的大作:《笑談軟體工程:例外處理設計的逆襲》公開在網路上下載,有興趣的不妨下載研究看看。

搞笑談軟工 - 毛書一刀未剪大公開


上一篇
Day 14 - [動詞二] 測試
下一篇
Day 16 - [形容詞] Access Modifiers
系列文
邁向專業軟體工程師必修的英文課30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言